//
//  ThemeExtension.swift
//  HeadlineNews
//
//  Created by han on 2019/7/22.
//  Copyright © 2019 han. All rights reserved.
//

import UIKit


// MARK: - UIView
//extension NSObject: ThemeExtendProtocol {}
extension ThemeExtended where T: UIView {
    var alpha: ThemeCGFloatPicker? {
        get { return getThemePicker(value, "setAlpha:") as? ThemeCGFloatPicker}
        set { setThemePicker(value, "setAlpha:", newValue)}
    }

    var backgroundColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setBackgroundColor:") as? ThemeColorPicker}
        set { setThemePicker(value, "setBackgroundColor:", newValue)}
    }

    var tintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setTintColor:", newValue) }
    }
}

// MARK: - UIApplication
extension ThemeExtended where T: UIApplication {
    func setStatusBarStyle(_ picker: ThemeStatusBarStylePicker, animated: Bool) {
        picker.animated = animated
        setThemePicker(value, "setStatusBarStyle:animated:", picker)
    }
}

// MARK: - UIBarItem
extension ThemeExtended where T: UIBarItem { // tabbarItem 的父类
    func titleTextAttributes(_ picker: ThemeDictionaryPicker, for state: UIControl.State) {
        let statePicker = makeThemeStatePicker(value, "setTitleTextAttributes:forState:", picker, state)
        setThemePicker(value, "setTitleTextAttributes:forState:", statePicker)
    }
    
    var image: ThemeImagePicker? {
        get { return getThemePicker(value, "setImage:") as? ThemeImagePicker }
        set { setThemePicker(value, "setImage:", newValue)}
    }
}

extension ThemeExtended where T: UITabBarItem {
    var selectedImage: ThemeImagePicker? {
        get { return getThemePicker(value, "setSelectedImage:") as? ThemeImagePicker }
        set { setThemePicker(value, "setSelectedImage:", newValue)}
    }
}

// MARK: - UIBarButtonItem
extension ThemeExtended where T: UIBarButtonItem {
    var tintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setTintColor:", newValue) }
    }
}

// MARK: - UINavigationBar
extension ThemeExtended where T: UINavigationBar {
    #if os(iOS)
    var barStyle: ThemeBarStylePicker? {
        get { return getThemePicker(value, "setBarStyle:") as? ThemeBarStylePicker }
        set { setThemePicker(value, "setBarStyle:", newValue)}
    }
    #endif
    
    var barTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setBarTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setBarTintColor:", newValue) }
    }
    
    var titleTextAttributes: ThemeDictionaryPicker? {
        get { return getThemePicker(value, "setTitleTextAttributes:") as? ThemeDictionaryPicker }
        set { setThemePicker(value, "setTitleTextAttributes:", newValue) }
    }
    var largeTitleTextAttributes: ThemeDictionaryPicker? {
        get { return getThemePicker(value, "setLargeTitleTextAttributes:") as? ThemeDictionaryPicker }
        set { setThemePicker(value, "setLargeTitleTextAttributes:", newValue) }
    }
}

// MARK: - UITabBar
extension ThemeExtended where T: UITabBar {
    #if os(iOS)
    var barStyle: ThemeBarStylePicker? {
        get { return getThemePicker(value, "setBarStyle:") as? ThemeBarStylePicker }
        set { setThemePicker(value, "setBarStyle:", newValue)}
    }
    #endif
    
    var barTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setBarTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setBarTintColor:", newValue) }
    }
}

// MARK: - UISearchBar
extension ThemeExtended where T: UISearchBar {
    #if os(iOS)
    var barStyle: ThemeBarStylePicker? {
        get { return getThemePicker(value, "setBarStyle:") as? ThemeBarStylePicker }
        set { setThemePicker(value, "setBarStyle:", newValue)}
    }
    #endif
    
    var barTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setBarTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setBarTintColor:", newValue)}
    }
    
    var keyboardAppearance: ThemeKeyboardAppearancePicker? {
        get { return getThemePicker(value, "setKeyboardAppearance:") as? ThemeKeyboardAppearancePicker }
        set { setThemePicker(value, "setKeyboardAppearance:", newValue) }
    }
}

// MARK: - UILabel
extension ThemeExtended where T: UILabel {
    var font: ThemeFontPicker? {
        get { return getThemePicker(value, "setFont:") as? ThemeFontPicker }
        set { setThemePicker(value, "setFont:", newValue)}
    }
    
    var textColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setTextColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setTextColor:", newValue)}
    }
    
    var shadowColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setHighlightedTextColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setHighlightedTextColor:", newValue)}
    }
    
    var highlightedTextColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setShadowColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setShadowColor:", newValue)}
    }
}

// MARK: - UITextField
extension ThemeExtended where T: UITextField {
    var font: ThemeFontPicker? {
        get { return getThemePicker(value, "setFont:") as? ThemeFontPicker }
        set { setThemePicker(value, "setFont:", newValue)}
    }
    
    var textColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setTextColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setTextColor:", newValue)}
    }
    
    var keyboardAppearance: ThemeKeyboardAppearancePicker? {
        get { return getThemePicker(value, "setKeyboardAppearance:") as? ThemeKeyboardAppearancePicker }
        set { setThemePicker(value, "setKeyboardAppearance:", newValue) }
    }
    
    var placeholderAttributes: ThemeDictionaryPicker? {
        get { return getThemePicker(value, "updatePlaceholderAttributes:") as? ThemeDictionaryPicker }
        set { setThemePicker(value, "updatePlaceholderAttributes:", newValue) }
    }
}

// MARK: - UITextView
extension ThemeExtended where T: UITextView {
    var font: ThemeFontPicker? {
        get { return getThemePicker(value, "setFont:") as? ThemeFontPicker }
        set { setThemePicker(value, "setFont:", newValue)}
    }
    
    var textColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setTextColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setTextColor:", newValue)}
    }
    
    var keyboardAppearance: ThemeKeyboardAppearancePicker? {
        get { return getThemePicker(value, "setKeyboardAppearance:") as? ThemeKeyboardAppearancePicker }
        set { setThemePicker(value, "setKeyboardAppearance:", newValue) }
    }
}

// MARK: - UIImageView
extension ThemeExtended where T: UIImageView {
    var image: ThemeImagePicker? {
        get { return getThemePicker(value, "setImage:") as? ThemeImagePicker }
        set { setThemePicker(value, "setImage:", newValue)}
    }
}

// MARK: - UIButton
extension ThemeExtended where T: UIButton {
    func setTitleColor(_ color: ThemeColorPicker?, for state: UIControl.State) {
        let statePicker = makeThemeStatePicker(value, "setTitleColor:forState:", color, state)
        setThemePicker(value, "setTitleColor:forState:", statePicker)
    }
    
    func setTitleShadowColor(_ color: ThemeColorPicker?, for state: UIControl.State) {
        let statePicker = makeThemeStatePicker(value, "setTitleShadowColor:forState:", color, state)
        setThemePicker(value, "setTitleShadowColor:forState:", statePicker)
    }
    
    func setImage(_ image: ThemeImagePicker?, for state: UIControl.State) {
        let statePicker = makeThemeStatePicker(value, "setImage:forState:", image, state)
        setThemePicker(value, "setImage:forState:", statePicker)
    }
    
    func setBackgroundImage(_ image: ThemeImagePicker?, for state: UIControl.State) {
        let statePicker = makeThemeStatePicker(value, "setBackgroundImage:forState:", image, state)
        setThemePicker(value, "setBackgroundImage:forState:", statePicker)
    }
}


// MARK: - UITableView
extension ThemeExtended where T: UITableView {
    var sectionIndexColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setSectionIndexColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setSectionIndexColor:", newValue) }
    }
    var sectionIndexBackgroundColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setSectionIndexBackgroundColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setSectionIndexBackgroundColor:", newValue) }
    }
    var sectionIndexTrackingBackgroundColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setSectionIndexTrackingBackgroundColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setSectionIndexTrackingBackgroundColor:", newValue) }
    }
    var separatorColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setSeparatorColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setSeparatorColor:", newValue) }
    }
}

// MARK: - UIScrollView
extension ThemeExtended where T: UIScrollView {
    var indicatorStyle: ThemeScrollViewIndicatorStylePicker? {
        get { return getThemePicker(value, "setIndicatorStyle:") as? ThemeScrollViewIndicatorStylePicker }
        set { setThemePicker(value, "setIndicatorStyle:", newValue)}
    }
}

// MARK: - UIActivityIndicatorView
extension ThemeExtended where T: UIActivityIndicatorView {
    var style: ThemeActivityIndicatorViewStylePicker? {
        get { return getThemePicker(value, "setActivityIndicatorViewStyle:") as? ThemeActivityIndicatorViewStylePicker }
        set { setThemePicker(value, "setActivityIndicatorViewStyle:", newValue)}
    }
}

// MARK: - UIProgressView
extension ThemeExtended where T: UIProgressView {
    var progressTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setProgressTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setProgressTintColor:", newValue) }
    }
    var trackTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setTrackTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setTrackTintColor:", newValue) }
    }
}

// MARK: - UIPageControl
extension ThemeExtended where T: UIPageControl {
    var pageIndicatorTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setPageIndicatorTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setPageIndicatorTintColor:", newValue) }
    }
    var currentPageIndicatorTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setCurrentPageIndicatorTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setCurrentPageIndicatorTintColor:", newValue) }
    }
}

// MARK: - CALayer
extension ThemeExtended where T: CALayer {
    var backgroundColor: ThemeCGColorPicker? {
        get { return getThemePicker(value, "setBackgroundColor:") as? ThemeCGColorPicker}
        set { setThemePicker(value, "setBackgroundColor:", newValue) }
    }
    var borderWidth: ThemeCGFloatPicker? {
        get { return getThemePicker(value, "setBorderWidth:") as? ThemeCGFloatPicker }
        set { setThemePicker(value, "setBorderWidth:", newValue) }
    }
    var borderColor: ThemeCGColorPicker? {
        get { return getThemePicker(value, "setBorderColor:") as? ThemeCGColorPicker }
        set { setThemePicker(value, "setBorderColor:", newValue) }
    }
    var shadowColor: ThemeCGColorPicker? {
        get { return getThemePicker(value, "setShadowColor:") as? ThemeCGColorPicker }
        set { setThemePicker(value, "setShadowColor:", newValue) }
    }
    var strokeColor: ThemeCGColorPicker? {
        get { return getThemePicker(value, "setStrokeColor:") as? ThemeCGColorPicker }
        set { setThemePicker(value, "setStrokeColor:", newValue) }
    }
    var fillColor: ThemeCGColorPicker?{
        get { return getThemePicker(value, "setFillColor:") as? ThemeCGColorPicker }
        set { setThemePicker(value, "setFillColor:", newValue) }
    }
}

#if os(iOS)

// MARK: - UIToolbar
extension ThemeExtended where T: UIToolbar {
    var barStyle: ThemeBarStylePicker? {
        get { return getThemePicker(value, "setBarStyle:") as? ThemeBarStylePicker }
        set { setThemePicker(value, "setBarStyle:", newValue) }
    }
    var barTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setBarTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setBarTintColor:", newValue) }
    }
}

// MARK: - UISwitch
extension ThemeExtended where T: UISwitch {
    var onTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setOnTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setOnTintColor:", newValue) }
    }
    var thumbTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setThumbTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setThumbTintColor:", newValue) }
    }
}

// MARK: - UISlider
extension ThemeExtended where T: UISlider {
    var thumbTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setThumbTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setThumbTintColor:", newValue) }
    }
    var minimumTrackTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setMinimumTrackTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setMinimumTrackTintColor:", newValue) }
    }
    var maximumTrackTintColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setMaximumTrackTintColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setMaximumTrackTintColor:", newValue) }
    }
}

// MARK: - UIPopoverPresentationController
extension ThemeExtended where T: UIPopoverPresentationController {
    var backgroundColor: ThemeColorPicker? {
        get { return getThemePicker(value, "setBackgroundColor:") as? ThemeColorPicker }
        set { setThemePicker(value, "setBackgroundColor:", newValue) }
    }
}

// MARK: - UIRefreshControl
extension ThemeExtended where T: UIRefreshControl {
    var titleAttributes: ThemeDictionaryPicker? {
        get { return getThemePicker(value, "updateTitleAttributes:") as? ThemeDictionaryPicker }
        set { setThemePicker(value, "updateTitleAttributes:", newValue) }
    }
}

#endif

// MARK: - private
private func setThemePicker(_ object: NSObject, _ selector: String, _ picker: ThemePicker?) {
    object.themePickers[selector] = picker
    object.theme.performPicker(selector: selector, picker: picker)
}

private func getThemePicker(_ object: NSObject, _ selector: String) -> ThemePicker? {
    return object.themePickers[selector]
}

private func makeThemeStatePicker(_ object: NSObject, _ selector: String, _ picker: ThemePicker?, _ state: UIControl.State) -> ThemePicker? {
    var picker = picker
    
    if let statePicker = object.themePickers[selector] as? ThemeStatePicker {
       picker = statePicker.setPicker(picker, forState: state)
    } else {
       picker = ThemeStatePicker(picker: picker, withState: state)
    }
    return picker
}

